<template>
  <h1>工具函数</h1>

  <p @click="person.name += '~'">{{ person.name }}</p>
  <p @click="person.age++">{{ person.age }}</p>
  <p @click="person.addresss.city += '!'">{{ person.addresss.city }}</p>
  <hr />

  <p @click="copy.name += '~'">{{ copy.name }}</p>
  <p @click="copy.age++">{{ copy.age }}</p>
  <p @click="copy.addresss.city += '!'">{{ copy.addresss.city }}</p>
</template>

<script>
import {
  ref,
  reactive,
  shallowReactive,
  readonly,
  shallowReadonly,
  computed,
  isRef,
  unref,
  toRef,
  toRefs,
  toValue,
  isReadonly
} from 'vue'

export default {
  setup() {
    const person = reactive({ name: '张三', age: 18, addresss: { city: '深圳市' } })

    const copy = shallowReadonly(person)
    return {
      person,
      copy
    }

    // ======================

    // const num = ref(1)
    // const person = reactive({ name: '张三', age: 18 })
    // const numPlus = computed(() => num.value + 1)

    // console.log(isRef(num)) // true
    // console.log(isRef(num.value)) // false
    // console.log(isRef(numPlus)) // true
    // console.log(isRef(person)) // false

    // console.log(unref(num)) // 1
    // console.log(unref(numPlus)) // 2
    // console.log(unref(person)) // Proxy({ name: '张三', age: 18 })

    /**
     * toRef
     *    作用：将一个响应式对象的某个属性的值转换成 ref 数据并返回。且返回的数据与原数据关联
     *    语法：
     *        toRef(target, prop)
     *
     * toRefs
     *    作用：将一个响应式对象的所有属性的值转换成 ref 数据并组转成一个普通的对象返回，且返回的数据与原数据关联
     *    语法：
     *        toRefs(target)
     */
    // const name = toRef(person, 'name')
    // name.value = '里斯'
    // console.log(person.name) // '里斯'

    // person.name = '王五'
    // console.log('name', name.value) // '王五'

    // const obj = toRefs(person)
    // console.log(obj) // { name: Ref, age: Ref }
    // obj.name.value = '王五'
    // console.log(person.name) // '王五'

    // person.name = '里斯'
    // console.log(obj.name.value) // '里斯'

    // 使用 toRefs 操作之后的数据，可以做解构
    // const { name, age } = toRefs(person)
    // person.name = '王五'
    // console.log(name.value) // '王五'

    // person.age = 20
    // console.log(age.value) // 20

    /**
     * toValue()  3.3 新增
     *    作用：与 unref 一样，多了一个功能点支持传入一个 getter 函数, 会自动将该 getter 函数执行，执行的返回值作为 toValue 的返回值
     *    getter: () => xxx
     */
    // console.log(toValue(num)) // 1
    // console.log(toValue(numPlus)) // 2
    // console.log(toValue(person)) // Proxy({ name: '张三', age: 18 })
    // console.log(toValue(() => '张三')) // '张三'

    // console.log(isReadonly(numPlus))
  }
}
</script>
